package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.dao.PaasProcessDataDao;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasFormSubDataEntity;
import com.xbongbong.paas.domain.entity.PaasPrintTemplateEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.impl.PaasFormExplainModelImpl;
import com.xbongbong.paas.pojo.dto.PaymentTaskMenuDTO;
import com.xbongbong.paas.pojo.dto.PaymentTaskMigrateDTO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.print.model.PaasPrintTemplateModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.PaymentTaskNotifyTypeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.menu.pojo.MenuReturnPojo;
import com.xbongbong.saas.domain.entity.CabinetFileEntity;
import com.xbongbong.saas.domain.entity.ContractUserEntity;
import com.xbongbong.saas.domain.entity.PaymentTaskSubDataEntity;
import com.xbongbong.saas.domain.entity.PaymentTaskUserEntity;
import com.xbongbong.saas.domain.entity.ext.PayPlanSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentTaskEntityExt;
import com.xbongbong.saas.enums.ExecutorCheckBoxEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PaymentTaskEnum;
import com.xbongbong.saas.enums.dictionary.PaymentTaskStatusEnum;
import com.xbongbong.saas.model.CabinetFileModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.PayPlanSheetModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.model.PaymentSubDataModel;
import com.xbongbong.saas.model.PaymentTaskModel;
import com.xbongbong.saas.model.PaymentTaskSubDataModel;
import com.xbongbong.saas.model.PaymentTaskUserModel;
import com.xbongbong.sys.domain.dao.UserConfigDao;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.domain.entity.RoleEntity;
import com.xbongbong.sys.domain.entity.UserConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.RoleModel;
import com.xbongbong.sys.model.UserConfigModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author: 汪腾伟
 * @date: 2020/9/17
 * @desrcption: 新回款计划脚本
 * @version:1.0
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/script/paymentTask")
public class PaymentTaskScriptController {

    private static final Logger LOG = LoggerFactory.getLogger(FundScriptController.class);

    @Resource
    private PaasProcessDataDao paasProcessDataDao;

    @Resource
    private EsHelper esHelper;

    @Resource
    private PaymentModel paymentModel;

    @Resource
    private ContractUserModel contractUserModel;

    @Resource
    private PaymentTaskModel paymentTaskModel;

    @Resource
    private PaymentTaskUserModel paymentTaskUserModel;

    @Resource
    private CompanyConfigModel companyConfigModel;

    @Resource
    private PaasFormModel paasFormModel;

    @Resource
    private UserConfigModel userConfigModel;

    @Resource
    private UserConfigDao userConfigDao;

    @Resource
    private CabinetFileModel cabinetFileModel;

    @Resource
    private RoleModel roleModel;
    @Resource
    private PaasPrintTemplateModel paasPrintTemplateModel;

    @Resource
    private PaymentSubDataModel paymentSubDataModel;

    @Resource
    private PaymentTaskSubDataModel paymentTaskSubDataModel;

    @Resource
    private PaymentSheetModel paymentSheetModel;

    @Resource
    private PayPlanSheetModel payPlanSheetModel;

    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private PaasFormExplainModelImpl paasFormExplainModel;

    /**
     * web端快捷新建配置
     */
    private static final String CONFIG_ALIAS_WEB = "quickNewForm_web";

    /**
     * dingtalk端快捷新建配置
     */
    private static final String CONFIG_ALIAS_DINGTALK = "quickNewForm_dingtalk";



    /**
     * 迁移老回款计划自定义字段到新回款计划自定义字段
     *
     * @param paymentTaskMigrateDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/migrateCustomField", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String migratePaymentTaskCustomField(@RequestBody @Valid PaymentTaskMigrateDTO paymentTaskMigrateDTO, BindingResult br) {
        XbbResponse<PaasFormDataEsListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                LOG.info("-----------迁移老回款计划自定义字段到新回款计划自定义字段-----------");
                //每次查询500条
                Integer pageNum = 500;
                Long idGte = 0L;
                Integer shouldUpdateTime = paymentTaskMigrateDTO.getShouldUpdateTime();
                Integer shouldUpdateEndTime = paymentTaskMigrateDTO.getShouldUpdateEndTime();
                Map<String, Object> paymentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                String paymentColumns = "id, corpid, explains";
                paymentMap.put("del", 0);
                paymentMap.put("businessType", XbbRefTypeEnum.PAYMENT.getCode());
                paymentMap.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
                paymentMap.put("shouldUpdateTime", shouldUpdateTime);
                paymentMap.put("shouldUpdateEndTime", shouldUpdateEndTime);
                Long maxId = paasFormExplainModel.getMaxId(paymentMap);
                Integer start = 0;
                paymentMap.put("start", start);
                paymentMap.put("pageNum", pageNum);
                paymentMap.put("orderByStr", "id asc");
                paymentMap.put("columns", paymentColumns);
                long timeStart = DateTimeUtil.getInt();
                //查询出新回款计划的默认模板解释
                Map<String, Object> paymentTempTaskMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                paymentTempTaskMap.put("corpid", "0");
                paymentTempTaskMap.put("del", 0);
                paymentTempTaskMap.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
                paymentTempTaskMap.put("businessType", XbbRefTypeEnum.PAYMENT_TASK.getCode());
                paymentTempTaskMap.put("columns", paymentColumns);
                List<PaasFormExplainEntity> paymentTaskTempExplainList = paasFormExplainModel.getNoHandleExplainsByFindEntitys(paymentTempTaskMap);
                List<FieldAttrEntity> paymentTaskFieldList = JSONArray.parseArray(paymentTaskTempExplainList.get(0).getExplains(), FieldAttrEntity.class);
                //查询出所有的新回款计划的数据
                paymentTempTaskMap.remove("corpid");
                while (true) {
                    paymentMap.put("idGte", idGte);
                    //获取要处理的数据
                    List<PaasFormExplainEntity> paymentExplainList = paasFormExplainModel.getNoHandleExplainsByFindEntitys(paymentMap);
                    LOG.warn("处理进度：已处理到 tb_paas_form_explain.id " + idGte + " / " + maxId);
                    if (CollectionUtils.isEmpty(paymentExplainList)) {
                        break;
                    }
                    idGte = paymentExplainList.get(paymentExplainList.size() - 1).getId();
                    List<String> corpidList = paymentExplainList.stream().map(u -> u.getCorpid()).collect(Collectors.toList());
                    //查询出所有的新回款计划的数据
                    paymentTempTaskMap.put("corpidIn", corpidList);
                    List<PaasFormExplainEntity> paymentTaskExplainList = paasFormExplainModel.getNoHandleExplainsByFindEntitys(paymentTempTaskMap);

                    int size = paymentExplainList.size();
                    HashMap<String, String> corpFinalFieldHashMap = new HashMap<>(size * 2);
                    //对老的回款计划进行自定义字段的获取，形成一个对应关系;公司id与新的自定义字段的一个对应关系
                    List<PaasFormExplainEntity> updateList = new ArrayList<>();
                    for (PaasFormExplainEntity paasFormExplainEntity : paymentExplainList) {
                        //获取老回款计划(现应收款)自定义字段列表
                        List<FieldAttrEntity> customFieldList = new ArrayList<>();
                        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                        if (CollectionsUtil.isEmpty(explainList)) {
                            continue;
                        }
                        //减少更新数据，没有自定义字段的老回款计划不做更新
                        for (FieldAttrEntity fieldAttrEntity : explainList) {
                            //对一些自定义字段遇到array_1,array_2,subForm_1需要重排
                            if (fieldAttrEntity.getIsRedundant() == 1) {
                                String attr = fieldAttrEntity.getAttr();
                                if (attr.contains("array_")) {
                                    String attrSub = attr.substring(6);
                                    fieldAttrEntity.setAttr("array_" + (Integer.parseInt(attrSub) + 2));
                                } else if (attr.contains("subForm_")) {
                                    String attrSub = attr.substring(8);
                                    fieldAttrEntity.setAttr("subForm_" + (Integer.parseInt(attrSub) + 1));
                                }
                                customFieldList.add(fieldAttrEntity);
                            }
                        }
                        if (CollectionsUtil.isNotEmpty(customFieldList)) {
                            paymentTaskFieldList.addAll(customFieldList);
                            String newField = JSON.toJSONString(paymentTaskFieldList);
                            corpFinalFieldHashMap.put(paasFormExplainEntity.getCorpid(), newField);
                            paymentTaskFieldList.removeAll(customFieldList);
                        }
                    }


                    //把自定义字段加到新回款计划上
                    for (PaasFormExplainEntity paymentTaskExplainEntity : paymentTaskExplainList) {
                        String corpid = paymentTaskExplainEntity.getCorpid();
                        if (corpFinalFieldHashMap.containsKey(corpid)) {
                            String shouldUpdateExplain = corpFinalFieldHashMap.get(corpid);
                            paymentTaskExplainEntity.setExplains(shouldUpdateExplain);
                            updateList.add(paymentTaskExplainEntity);
                        }
                    }
                    if (CollectionsUtil.isNotEmpty(updateList)) {
                        paasFormExplainModel.updateBatchExplains(updateList);
                    }
                }
                LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
                LOG.info("-----------/script/paymentTask/migrateCustomField over");
            } catch (Exception e) {
                LOG.error("批量更新回款计划字段解释报错:" + e.getMessage());
            }
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");

    }


    /**
     * 处理老的审批中的回款计划数据，处理要按照以下三步
     * （1）老的回款计划数据格式要按照新的回款计划进行处理
     * （2）针对已经审批过的合同订单，并且重新进入审批中，目前合同订单在审批中，这时候需要把合同订单中的老回款计划remove掉，因为这时候已经有应收款了
     * (3)针对合同没有签订人的直接拒绝，因为目前想让合同签订人做新回款计划执行人
     * (4)针对array类型后面值需要加2，针对subForm类型后面值需要加1
     * <p>
     * 对照关系
     * 老回款计划             新回款计划
     * 编号            serialNo                 serialNo
     * 计划收款金额     num_1                     num_1
     * 回款状态        text_3                      text_5
     * 回款类型        text_6                      text_8
     * 预计回款日期     date_1                   date_1
     * 备注           text_7                     text_10
     * 提醒           以前没有              对应过来，默认是不提醒： text_4 = 0
     *
     * @param paymentTaskMigrateDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/migrateOldProcessData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String migrateOldProcessData(@RequestBody @Valid PaymentTaskMigrateDTO paymentTaskMigrateDTO, BindingResult br) {
        try {
            LOG.info("-----------迁移合同中带有回款计划的数据-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> processDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            processDataMap.put("del", 0);
            processDataMap.put("businessType", XbbRefTypeEnum.CONTRACT.getCode());
            //每次查询500条
            Integer pageNum = 500;
            Long idGte = 0L;
            Long maxId = paasProcessDataDao.getMaxId(processDataMap);
            Integer start = 0;
            processDataMap.put("start", start);
            processDataMap.put("pageNum", pageNum);
            processDataMap.put("orderByStr", "id asc");
            while (true) {
                processDataMap.put("idGte", idGte);
                //获取要处理的数据
                List<PaasProcessDataEntity> processDataEntities = paasProcessDataDao.findEntitys(processDataMap);
                LOG.warn("处理进度：已处理到 tb_paas_process_data.id " + idGte + " / " + maxId);
                if (CollectionUtils.isEmpty(processDataEntities)) {
                    break;
                }
                idGte = processDataEntities.get(processDataEntities.size() - 1).getId();
                Set<String> corpidList = new HashSet<>();
                for (PaasProcessDataEntity paasProcessDataEntity : processDataEntities) {
                    corpidList.add(paasProcessDataEntity.getCorpid());
                }
                //获取老回款计划(应收款)的表单解释列表
                String paymentColumns = "id, corpid, explains";
                List<PaasFormExplainEntity> paymentExplainList = getPaasFormExplainList(corpidList, XbbRefTypeEnum.PAYMENT.getCode(), paymentColumns);
                HashMap<String, List<String>> corpCustomHashMap = getCustomFieldList(paymentExplainList);
                List<PaasProcessDataEntity> updateList = new ArrayList<>();
                StringBuilder stringBuilder = new StringBuilder();
                for (PaasProcessDataEntity paasProcessDataEntity : processDataEntities) {
                    String data = paasProcessDataEntity.getData();
                    JSONObject jsonObject = JSON.parseObject(data);
                    JSONArray jsonArray = jsonObject.getJSONArray("array_1");
                    if (Objects.isNull(jsonArray)) {
                        continue;
                    }
                    stringBuilder.append(paasProcessDataEntity.getId());
                    stringBuilder.append(SymbolConstant.COMMA_ENGLISH);
                    //负责人、协同人
                    List<String> contractUserList = new ArrayList<>();
                    JSONArray ownerIdArray = jsonObject.getJSONArray(PaymentEnum.OWNER_ID.getAttr());
                    JSONArray coOwnerIdArray = jsonObject.getJSONArray(PaymentEnum.COUSERID.getAttr());
                    if (Objects.nonNull(ownerIdArray)) {
                        List<String> ownerList = JSONObject.parseArray(ownerIdArray.toJSONString(), String.class);
                        contractUserList.addAll(ownerList);
                    }
                    if (Objects.nonNull(coOwnerIdArray)) {
                        List<String> coOwnerList = JSONObject.parseArray(coOwnerIdArray.toJSONString(), String.class);
                        contractUserList.addAll(coOwnerList);
                    }

                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObjectSen = jsonArray.getJSONObject(i);
                        JSONObject jsonObjectThree = (JSONObject) jsonObjectSen.get("data");
                        List<String> customFieldList = corpCustomHashMap.get(paasProcessDataEntity.getCorpid());
                        //获取最后得到的jsonObject
                        JSONObject fininalJsonObject = getFininalJsonObject(jsonObjectThree, null, customFieldList, contractUserList, 2);
                        jsonObjectSen.put("data", fininalJsonObject);
                    }
                    //JSON转回去
                    String fininalJson = JSON.toJSONString(jsonObject);
                    paasProcessDataEntity.setData(fininalJson);
                    updateList.add(paasProcessDataEntity);
                }
                //获取相应公司的新回款计划表单解释
                String paymentTaskColumns = "id, corpid, app_id, menu_id, form_id";
                List<PaasFormExplainEntity> paymentTaskExplainList = getPaasFormExplainList(corpidList, XbbRefTypeEnum.PAYMENT_TASK.getCode(), paymentTaskColumns);
                //这些需要更新的审批老数据同时也需要更新form_id,menu_id,app_id
                //---------------下面是对data以外的参数进行封装，比如form_id,menu_id,app_id
                Map<String, PaasFormExplainEntity> taskExplainMap = paymentTaskExplainList.stream().collect(Collectors.toMap(e -> e.getCorpid(), Function.identity()));
                for (PaasProcessDataEntity paasProcessDataEntity : updateList) {
                    PaasFormExplainEntity taskExplain = taskExplainMap.get(paasProcessDataEntity.getCorpid());
                    if (Objects.nonNull(taskExplain)) {
                        paasProcessDataEntity.setAppId(taskExplain.getAppId());
                        paasProcessDataEntity.setMenuId(taskExplain.getMenuId());
                        paasProcessDataEntity.setFormId(taskExplain.getFormId());
                    }
                }
                try {
                    if (CollectionsUtil.isNotEmpty(updateList)) {
                        paasProcessDataDao.updateBatchProcessData(updateList);
                        //清理大对象
                        processDataEntities.clear();
                        updateList.clear();
                    }
                } catch (Exception e) {
                    LOG.error("/script/paymentTask/migrateOldProcessData  error processDataId:" + stringBuilder.toString(), e);
                }
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/paymentTask/migrateOldProcessData over");
        } catch (Exception e) {
            LOG.error("迁移合同中带有回款计划的数据:" + e, e);
            return JSON.toJSONString("{\"msg\":\"fail\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 迁移老回款计划数据到新回款计划中
     *
     * @param paymentTaskMigrateDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/migrateOldPaymentToPaymentTask", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String migrateOldPaymentToPaymentTask(@RequestBody @Valid PaymentTaskMigrateDTO paymentTaskMigrateDTO, BindingResult br) {
        try {
            LOG.info("-----------老回款计划数据到新回款计划中-----------");
            long timeStart = DateTimeUtil.getInt();
            Integer shouldUpdateTime = paymentTaskMigrateDTO.getShouldUpdateTime();
            Integer shouldUpdateEndTime = paymentTaskMigrateDTO.getShouldUpdateEndTime();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", 0);
            param.put("shouldUpdateTime",shouldUpdateTime);
            param.put("shouldUpdateEndTime",shouldUpdateEndTime);
            Long maxId = paymentModel.getMaxId(param);
            Integer start = 0;
            //每次查询500条
            Integer pageNum = 500;
            Long idGte = 0L;
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            String columns = "id, corpid, app_id, menu_id, form_id";
            Long updateDatabaseTime = DateUtil.getNow();
            while (true) {
                param.put("idGte", idGte);
                LOG.warn("处理进度：已处理到 tb_saas_payment.id " + idGte + " / " + maxId);
                List<PaymentEntityExt> paymentEntityExts = paymentModel.findEntitys(param);
                if (CollectionUtils.isEmpty(paymentEntityExts)) {
                    break;
                }
                Set<Long> contractList = new HashSet<>();
                Set<String> corpidList = new HashSet<>();
                Map<Long, Long> contractLinkPayment = new HashMap<>((paymentEntityExts.size()));
                StringBuilder stringBuilder = new StringBuilder();
                for (PaymentEntityExt paymentEntityExt : paymentEntityExts) {
                    stringBuilder.append(paymentEntityExt.getId());
                    stringBuilder.append(SymbolConstant.COMMA_ENGLISH);
                    JSONObject jsonObject = paymentEntityExt.getData();
                    Long contractId = jsonObject.getLong(PaymentEnum.CONTRACT.getAttr());
                    contractList.add(contractId);
                    corpidList.add(paymentEntityExt.getCorpid());
                    contractLinkPayment.put(paymentEntityExt.getId(), contractId);
                    if (Objects.isNull(shouldUpdateEndTime)) {
                        paymentEntityExt.setUpdateTime(updateDatabaseTime);
                    }else {
                        paymentEntityExt.setUpdateTime(shouldUpdateEndTime.longValue());
                    }
                    jsonObject.put(PaymentEnum.SOURCE_REF_TYPE.getAttr(), XbbRefTypeEnum.PAYMENT_TASK.getCode());
                    jsonObject.put(PaymentEnum.SOURCE.getAttr(), String.valueOf(paymentEntityExt.getId()));
                    jsonObject.put(PaymentEnum.SOURCE_LINK_TEXT.getAttr(), paymentEntityExt.getSerialNo());
                }

                //获取相应公司的老回款计划表单解释
                List<PaasFormExplainEntity> paymentExplainList = getPaasFormExplainList(corpidList, XbbRefTypeEnum.PAYMENT.getCode(), columns);

                //根据合同id列表去查询合同的团队信息
                Map<String, Object> contractParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                contractParam.put("del", 0);
                contractParam.put("contractIdIn", contractList);
                List<ContractUserEntity> contractUserEntityList = contractUserModel.findEntitys(contractParam);
                //根据合同去做一个分组，contractId与User的对应关系
                Map<Long, List<ContractUserEntity>> contractMap = contractUserEntityList.stream().collect(Collectors.groupingBy(ContractUserEntity::getDataId));

                //获取相应公司的新回款计划表单解释
                List<PaasFormExplainEntity> paymentTaskExplainList = getPaasFormExplainList(corpidList, XbbRefTypeEnum.PAYMENT_TASK.getCode(), columns);

                //---------------------封装要保存到新回款计划的参数
                HashMap<String, List<PaymentTaskEntityExt>> hashMap = getInsertPaymentTaskList(paymentEntityExts, contractMap, paymentExplainList, paymentTaskExplainList, shouldUpdateTime, shouldUpdateEndTime);
                //回款计划新增
                List<PaymentTaskEntityExt> paymentTaskEntityExtInsertList = hashMap.get("1");
                //回款计划更新
                List<PaymentTaskEntityExt> paymentTaskEntityExtUpdateList = hashMap.get("2");
                List<PaymentTaskUserEntity> paymentTaskUserEntityList = getPaymentTaskUserList(paymentEntityExts, contractMap, contractLinkPayment);

                //--------------------(1)批量插入回款计划用户到用户表中 (2)更新
                //更新的执行者信息
                List<PaymentTaskUserEntity> updatePaymentTaskUserList = new ArrayList<>();
                for (PaymentTaskEntityExt paymentTaskEntityExt : paymentTaskEntityExtUpdateList) {
                    Long id = paymentTaskEntityExt.getId();
                    for (PaymentTaskUserEntity paymentTaskUserEntity : paymentTaskUserEntityList) {
                        if (id.equals(paymentTaskUserEntity.getDataId())) {
                            updatePaymentTaskUserList.add(paymentTaskUserEntity);
                        }
                    }
                }
                if (CollectionsUtil.isNotEmpty(paymentTaskUserEntityList)) {
                    paymentTaskUserEntityList.removeAll(updatePaymentTaskUserList);
                }

                try {
                    //---------------------(1)批量插入到数据库中; (2)批量更新数据库
                    if (CollectionsUtil.isNotEmpty(paymentTaskEntityExtInsertList)) {
                        paymentTaskModel.insertBatchIncludId(paymentTaskEntityExtInsertList);

                        //---------------------反向更新应收款，来源单据
                        paymentModel.updateBatchAll(paymentEntityExts);
                    }
                    if (CollectionsUtil.isNotEmpty(paymentTaskEntityExtUpdateList)) {
                        paymentTaskModel.updateAll(paymentTaskEntityExtUpdateList);
                    }
                    //插入操作
                    if (CollectionsUtil.isNotEmpty(paymentTaskUserEntityList)) {
                        paymentTaskUserModel.insertBatch(paymentTaskUserEntityList);
                    }
                } catch (Exception e) {
                    LOG.error("/script/paymentTask/migrateOldPaymentToPaymentTask  error paymentIds:" + stringBuilder.toString(), e);
                }
                idGte = paymentEntityExts.get(paymentEntityExts.size() - 1).getId();
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/paymentTask/migrateOldPaymentToPaymentTask over");
        } catch (Exception e) {
            LOG.error("/script/paymentTask/migrateOldPaymentToPaymentTask  error", e);
            return JSON.toJSONString("{\"msg\":\"e\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 获取返回需要插入的回款计划列表
     * <p>
     * 对照关系
     * 老回款计划             新回款计划
     * 编号            serialNo                 serialNo
     * 客户            text_4                   text_2
     * 客户名称         text_10                  text_6
     * 合同            text_5                    text_3
     * 合同名称         text_11                 text_7
     * 计划收款金额     num_1                     num_1
     * 回款状态        text_3                      text_5
     * 回款类型        text_6                      text_8
     * 预计回款日期     date_1                   date_1
     * 备注           text_7                     text_10
     * 提醒           以前没有              对应过来，默认是不提醒： text_4 = 0
     * <p>
     * 老回款计划只要未收金额大于0的话，对应新回款计划未完成
     *
     * @return
     */
    private HashMap<String, List<PaymentTaskEntityExt>> getInsertPaymentTaskList(List<PaymentEntityExt> paymentEntityExts, Map<Long, List<ContractUserEntity>> contractMap,
                                                                List<PaasFormExplainEntity> paymentExplainList, List<PaasFormExplainEntity> paymentTaskExplainList, Integer shouldUpdateTime,
                                                                Integer endTime) {
        HashMap<String, List<String>> corpCustomHashMap = getCustomFieldList(paymentExplainList);
        HashMap<String, List<PaymentTaskEntityExt>> hashMap = new HashMap<>((paymentEntityExts.size()) * 2);
        List<PaymentTaskEntityExt> insertPaymentTaskList = new ArrayList<>();
        List<PaymentTaskEntityExt> updatePaymentTaskList = new ArrayList<>();
        //----------------------下面是进行data参数的一些封装
        for (PaymentEntityExt paymentEntityExt : paymentEntityExts) {
            JSONObject jsonObject = paymentEntityExt.getData();
            PaymentTaskEntityExt paymentTaskEntityExt = new PaymentTaskEntityExt();
            BeanUtil.copyProperties(paymentEntityExt, paymentTaskEntityExt);
            String contractIdStr = paymentEntityExt.getData().getString(PaymentEnum.CONTRACT.getAttr());
            if (Objects.isNull(contractIdStr)) {
                continue;
            }
            //自定义执行人具体的值
            List<ContractUserEntity> contractUserEntityList = contractMap.get(Long.parseLong(paymentEntityExt.getData().getString(PaymentEnum.CONTRACT.getAttr())));
            //对自定义字段的处理
            List<String> keyList = corpCustomHashMap.get(paymentEntityExt.getCorpid());
            JSONObject jsonObjectSen = getFininalJsonObject(jsonObject, contractUserEntityList, keyList, null, 1);
            paymentTaskEntityExt.setData(jsonObjectSen);
            paymentTaskEntityExt.setSysLong10(ModelTypeEnum.PLAN.getCode());
            //区别哪些需要更新，哪些需要新增 第一次刷肯定是增量的，后置刷可能会有一些更新
            if (paymentEntityExt.getAddTime() < shouldUpdateTime && (paymentEntityExt.getUpdateTime() > shouldUpdateTime)) {
                updatePaymentTaskList.add(paymentTaskEntityExt);
            }else {
                insertPaymentTaskList.add(paymentTaskEntityExt);
            }


        }

        //---------------下面是对data以外的参数进行封装，比如form_id,menu_id,app_id
        Map<String, PaasFormExplainEntity> taskExplainMap = paymentTaskExplainList.stream().collect(Collectors.toMap(e -> e.getCorpid(), Function.identity()));
        for (PaymentTaskEntityExt paymentTaskEntityExt : insertPaymentTaskList) {
            PaasFormExplainEntity taskExplain = taskExplainMap.get(paymentTaskEntityExt.getCorpid());
            if (Objects.nonNull(taskExplain)) {
                paymentTaskEntityExt.setAppId(taskExplain.getAppId());
                paymentTaskEntityExt.setMenuId(taskExplain.getMenuId());
                paymentTaskEntityExt.setFormId(taskExplain.getFormId());
            }
        }
        hashMap.put("1", insertPaymentTaskList);
        hashMap.put("2", updatePaymentTaskList);
        return hashMap;
    }

    /**
     * 根据条件获取表单解释
     *
     * @return
     */
    private List<PaasFormExplainEntity> getPaasFormExplainList(Set<String> corpidList, int businessType, String showColumn) {
        Map<String, Object> paymentTaskExplainParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paymentTaskExplainParam.put("businessType", businessType);
        paymentTaskExplainParam.put("del", 0);
        paymentTaskExplainParam.put("columns", showColumn);
        paymentTaskExplainParam.put("corpidIn", corpidList);
        paymentTaskExplainParam.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
        List<PaasFormExplainEntity> paymentTaskExplainList = paasFormExplainModel.getNoHandleExplainsByFindEntitys(paymentTaskExplainParam);
        return paymentTaskExplainList;
    }

    /**
     * 获取最后的jsonObject
     *
     * @param jsonObject
     * @param migrationType=1代表是迁移数据 type=2代表是迁移审批中的数据
     * @return
     */
    private JSONObject getFininalJsonObject(JSONObject jsonObject, List<ContractUserEntity> contractUserEntityList,
                                            List<String> keyList, List<String> contractUserList, int migrationType) {
        if (Objects.isNull(jsonObject)) {
            return null;
        }
        JSONObject jsonObjectSen = new JSONObject();
        //老回款计划未收金额,如果为空的话就是已完成的状态
        double unAmount = jsonObject.getDoubleValue(PaymentEnum.UN_AMOUNT.getAttr());
        if (unAmount > 0) {
            jsonObjectSen.put(PaymentTaskEnum.STATUS.getAttr(), PaymentTaskStatusEnum.NO_FINISH.getCode());
            //计划收款金额，现在未完成的回款计划要按照应收款的未收金额刷，已完成的回款计划要按照计划金额问题
            jsonObjectSen.put(PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr(), unAmount);
        } else {
            jsonObjectSen.put(PaymentTaskEnum.STATUS.getAttr(), PaymentTaskStatusEnum.FINISH.getCode());
            double planAmount = jsonObject.getDoubleValue(PaymentEnum.AMOUNT.getAttr());
            jsonObjectSen.put(PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr(), planAmount);
        }
        //客户
        String customerId = jsonObject.getString(PaymentEnum.CUSTOMER.getAttr());
        jsonObjectSen.put(PaymentTaskEnum.LINK_CUSTOMER.getAttr(), customerId);
        //客户名称
        String customerName = jsonObject.getString(PaymentEnum.CUSTOMER_LINK_TEXT.getAttr());
        jsonObjectSen.put(PaymentTaskEnum.LINK_CUSTOMER_HIDE.getAttr(), customerName);
        //合同
        String contractId = jsonObject.getString(PaymentEnum.CONTRACT.getAttr());
        jsonObjectSen.put(PaymentTaskEnum.LINK_CONTRACT.getAttr(), contractId);
        //合同名称
        String contractName = jsonObject.getString(PaymentEnum.CONTRACT_LINK_TEXT.getAttr());
        jsonObjectSen.put(PaymentTaskEnum.LINK_CONTRACT_HIDE.getAttr(), contractName);
        //回款类型
        String type = jsonObject.getString(PaymentEnum.PAYMENT_TYPE.getAttr());
        jsonObjectSen.put(PaymentTaskEnum.PAYMENT_TASK_TYPE.getAttr(), type);
        //预计回款日期
        Long paymentTime = jsonObject.getLong(PaymentEnum.ESTIMATE_TIME.getAttr());
        jsonObjectSen.put(PaymentTaskEnum.EXECUTOR_TIME.getAttr(), paymentTime);
        //备注
        String memo = jsonObject.getString(PaymentEnum.MEMO.getAttr());
        jsonObjectSen.put(PaymentTaskEnum.MEMO.getAttr(), memo);
        //提醒，默认是不提醒的
        jsonObjectSen.put(PaymentTaskEnum.NOTIFY_TYPE.getAttr(), PaymentTaskNotifyTypeEnum.NO_NOTIFY.getCode().toString());
        //执行人(都是自定义执行人) 0:负责人 1:协同人 2:自定义执行人,这边需要的是字符串
        jsonObjectSen.put(PaymentTaskEnum.EXECUTOR.getAttr(), Arrays.asList(ExecutorCheckBoxEnum.CUSTOM_CHECK.getCode().toString()));
        //自定义执行人具体的值,这里因为有两个入口，有两个不同的处理方式
        if (CollectionsUtil.isNotEmpty(contractUserEntityList)) {
            List<String> executorTextList = contractUserEntityList.stream().map(ContractUserEntity::getUserId).collect(Collectors.toList());
            jsonObjectSen.put(PaymentTaskEnum.EXECUTOR_LINKED_TEXT.getAttr(), executorTextList);
        } else if (CollectionsUtil.isNotEmpty(contractUserList)) {
            jsonObjectSen.put(PaymentTaskEnum.EXECUTOR_LINKED_TEXT.getAttr(), contractUserList);
        } else {
            jsonObjectSen.put(PaymentTaskEnum.EXECUTOR_LINKED_TEXT.getAttr(), Arrays.asList(""));
        }
        //--------------------------审批中的数据全部处理，但是在列表中的数据需要过滤自定义子表单的数据，遇到subForm类型的数据就不处理了
        //对自定义字段的处理
        //只有对应公司的模板自定义字段存在的话才会走下面逻辑
        if (Objects.nonNull(jsonObject)) {
            for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
                String key = entry.getKey();
                if (CollectionsUtil.isNotEmpty(keyList)) {
                    //代表是自定义字段
                    boolean customKeyExist = keyList.contains(key);
                    if (customKeyExist) {
                        Object value = entry.getValue();
                        if (key.contains("array_")) {
                            String newKey = "array_" + (Integer.parseInt(key.substring(6, key.length())) + 2);
                            jsonObjectSen.put(newKey, value);
                        } else if (migrationType == 2 && key.contains("subForm_")) {
                            //只有在进行审批的时候才需要对这种子表单数据的处理
                            String newKey = "subForm_" + (Integer.parseInt(key.substring(8, key.length())) + 1);
                            jsonObjectSen.put(newKey, value);
                        } else if (!key.contains("array_") && !key.contains("subForm_")){
                            jsonObjectSen.put(key, value);
                        }
                    }
                }
            }
        }
        return jsonObjectSen;
    }


    /**
     * 获取(老回款计划)现应收款自定义字段，公司与自定义字段对应
     *
     * @param paymentExplainList
     * @return
     */
    private HashMap<String, List<String>> getCustomFieldList(List<PaasFormExplainEntity> paymentExplainList) {
        int size = paymentExplainList.size();
        HashMap<String, List<String>> corpCustomHashMap = new HashMap<>(size * 2);
        //获取一个corpid与自定义表单解释进行对应的关系
        for (PaasFormExplainEntity paasFormExplainEntity : paymentExplainList) {
            //获取回款计划自定义attr列表
            List<String> customFieldList = new ArrayList<>();
            List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            if (CollectionsUtil.isEmpty(explainList)) {
                continue;
            }
            for (FieldAttrEntity fieldAttrEntity : explainList) {
                if (fieldAttrEntity.getIsRedundant() == 1) {
                    customFieldList.add(fieldAttrEntity.getAttr());
                }
            }
            if (CollectionsUtil.isNotEmpty(customFieldList)) {
                corpCustomHashMap.put(paasFormExplainEntity.getCorpid(), customFieldList);
            }
        }
        return corpCustomHashMap;
    }


    /**
     * 获取需要插入的回款计划用户列表，因为目前采用老回款计划和新回款计划采用的id是对应的
     *
     * @param paymentEntityExts
     * @return
     */
    private List<PaymentTaskUserEntity> getPaymentTaskUserList(List<PaymentEntityExt> paymentEntityExts, Map<Long, List<ContractUserEntity>> contractMap,  Map<Long, Long> contractLinkPayment) {
        List<PaymentTaskUserEntity> paymentTaskUserEntities = new ArrayList<>();
        for (PaymentEntityExt paymentEntityExt : paymentEntityExts) {
            for (Map.Entry<Long, Long> entry : contractLinkPayment.entrySet()) {
                Long paymentId = entry.getKey();
               if (Objects.equals(paymentEntityExt.getId(), paymentId)) {
                   Long contractId = entry.getValue();
                   List<ContractUserEntity> contractUserEntityList = contractMap.get(contractId);
                   if (CollectionUtils.isEmpty(contractUserEntityList)) {
                       break;
                   }
                   for (ContractUserEntity contractUserEntity : contractUserEntityList) {
                       PaymentTaskUserEntity paymentTaskUserEntity = new PaymentTaskUserEntity();
                       BeanUtil.copyProperties(contractUserEntity, paymentTaskUserEntity);
                       if (Objects.isNull(contractUserEntity.getUserAvatar())) {
                           paymentTaskUserEntity.setUserAvatar("");
                       }
                       paymentTaskUserEntity.setDataId(paymentId);
                       paymentTaskUserEntities.add(paymentTaskUserEntity);
                   }
               }
           }
       }
       return paymentTaskUserEntities;
    }

    /**
     * 修改公司级别老回款计划快捷新建菜单中的menuId为新回款计划菜单中的menuId
     * userConfig true：代表是用户级别
     * companyConfig true：代表是公司级
     *
     * @param paymentTaskMenuDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/fixCompanyPaymentTaskMenuId", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixCompanyPaymentTaskMenuId(@RequestBody @Valid PaymentTaskMenuDTO paymentTaskMenuDTO, BindingResult br) {
        try {
            LOG.info("-----------修改公司配置回款计划的menuId-----------");
            String paramCorpid = paymentTaskMenuDTO.getCorpid();
            Set<String> corpidSet = paymentTaskMenuDTO.getCorpidList();
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", 0);
            List<String> companyConfigList = Arrays.asList(CONFIG_ALIAS_WEB, CONFIG_ALIAS_DINGTALK);
            param.put("configAliasIn", companyConfigList);
            if (Objects.nonNull(paramCorpid)) {
                param.put("corpid", paramCorpid);
            } else if (CollectionsUtil.isNotEmpty(corpidSet)) {
                param.put("corpidList", corpidSet);
            }
            Long maxId = companyConfigModel.getMaxId(param);
            Integer start = 0;
            //每次查询500条
            Integer pageNum = 500;
            Long idGte = 0L;
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            while (true) {
                param.put("idGte", idGte);
                LOG.warn("处理进度：已处理到 tb_company_config.id " + idGte + " / " + maxId);
                List<CompanyConfigEntity> companyConfigEntities = companyConfigModel.findEntitys(param);
                if (CollectionUtils.isEmpty(companyConfigEntities)) {
                    break;
                }
                Set<String> companySet = new HashSet<>();
                companyConfigEntities.forEach(companyConfigEntity -> {
                    companySet.add(companyConfigEntity.getCorpid());
                });
                //获取应收款corpid与menuId的对应关系
                List<PaasFormEntityExt> paymentPaasFormEntityExts = getPaasFormEntityList(XbbRefTypeEnum.PAYMENT.getCode(), companySet);
                int size = paymentPaasFormEntityExts.size();
                HashMap<String, Long> hashMap = new HashMap<>(size * 2);
                paymentPaasFormEntityExts.forEach(paasFormEntityExt -> hashMap.put(paasFormEntityExt.getCorpid(), paasFormEntityExt.getMenuId()));

                //新回款计划corpid和menuId的对应关系
                List<PaasFormEntityExt> paymentTaskPaasFormEntityExts = getPaasFormEntityList(XbbRefTypeEnum.PAYMENT_TASK.getCode(), companySet);
                int sizeSen = paymentPaasFormEntityExts.size();
                HashMap<String, Long> paymentTaskHashMap = new HashMap<>(sizeSen * 2);
                paymentTaskPaasFormEntityExts.forEach(paasFormEntityExt -> paymentTaskHashMap.put(paasFormEntityExt.getCorpid(), paasFormEntityExt.getMenuId()));

                //找出应收款菜单，并把应收款的菜单id改成应收款的菜单id
                List<CompanyConfigEntity> updateList = new ArrayList<>();
                for (CompanyConfigEntity companyConfigEntity : companyConfigEntities) {
                    //需要更新的标记则为true
                    boolean updateTag = false;
                    String corpid = companyConfigEntity.getCorpid();
                    //应收款的菜单
                    Long paymentMenuId = hashMap.get(corpid);
                    String configValue = companyConfigEntity.getConfigValue();
                    List<MenuReturnPojo> quickNewFormList = JSONObject.parseArray(configValue, MenuReturnPojo.class);
                    for (MenuReturnPojo menuReturnPojo : quickNewFormList) {
                        if (menuReturnPojo.getMenuId().equals(paymentMenuId)) {
                            //回款计划的菜单
                            Long paymentTaskMenuId = paymentTaskHashMap.get(corpid);
                            menuReturnPojo.setMenuId(paymentTaskMenuId);
                            updateTag = true;
                        }
                    }
                    //封装好参数之后，需要重新重新拼接返回
                    if (!updateTag) {
                        continue;
                    }
                    String newConfigValue = JSON.toJSONString(quickNewFormList);
                    companyConfigEntity.setConfigValue(newConfigValue);
                    updateList.add(companyConfigEntity);
                }
                //进行批量更新菜单表
                if (CollectionsUtil.isNotEmpty(updateList)) {
                    companyConfigModel.updateBatch4Script(updateList);
                }
                idGte = companyConfigEntities.get(companyConfigEntities.size() - 1).getId();
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/paymentTask/fixCompanyPaymentTaskMenuId over");
        } catch (Exception e) {
            LOG.error("/script/paymentTask/fixCompanyPaymentTaskMenuId  error", e);
            return JSON.toJSONString("{\"msg\":\"fail\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 修改用户级别老回款计划快捷新建菜单中的menuId为新回款计划菜单中的menuId
     * userConfig true：代表是用户级别
     * companyConfig true：代表是公司级
     *
     * @param paymentTaskMenuDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/fixUserPaymentTaskMenuId", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixUserPaymentTaskMenuId(@RequestBody @Valid PaymentTaskMenuDTO paymentTaskMenuDTO, BindingResult br) {
        try {
            LOG.info("-----------修改用户配置回款计划的menuId-----------");
            String paramCorpid = paymentTaskMenuDTO.getCorpid();
            Set<String> corpidSet = paymentTaskMenuDTO.getCorpidList();
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", 0);
            List<String> userConfigList = Arrays.asList(CONFIG_ALIAS_WEB, CONFIG_ALIAS_DINGTALK);
            param.put("configAliasIn", userConfigList);
            if (Objects.nonNull(paramCorpid)) {
                param.put("corpid", paramCorpid);
            } else if (CollectionsUtil.isNotEmpty(corpidSet)) {
                param.put("corpidList", corpidSet);
            }
            Long maxId = userConfigModel.getMaxId(param);
            Integer start = 0;
            //每次查询500条
            Integer pageNum = 500;
            Long idGte = 0L;
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            while (true) {
                param.put("idGte", idGte);
                LOG.warn("处理进度：已处理到 tb_user_config.id " + idGte + " / " + maxId);
                List<UserConfigEntity> userConfigDaoEntitys = userConfigDao.findEntitys(param);
                if (CollectionUtils.isEmpty(userConfigDaoEntitys)) {
                    break;
                }
                Set<String> companySet = new HashSet<>();
                userConfigDaoEntitys.forEach(companyConfigEntity -> {
                    companySet.add(companyConfigEntity.getCorpid());
                });
                //获取应收款corpid与menuId的对应关系
                List<PaasFormEntityExt> paymentPaasFormEntityExts = getPaasFormEntityList(XbbRefTypeEnum.PAYMENT.getCode(), companySet);
                int size = paymentPaasFormEntityExts.size();
                HashMap<String, Long> hashMap = new HashMap<>(size * 2);
                paymentPaasFormEntityExts.forEach(paasFormEntityExt -> hashMap.put(paasFormEntityExt.getCorpid(), paasFormEntityExt.getMenuId()));

                //新回款计划corpid和menuId的对应关系
                List<PaasFormEntityExt> paymentTaskPaasFormEntityExts = getPaasFormEntityList(XbbRefTypeEnum.PAYMENT_TASK.getCode(), companySet);
                int sizeSen = paymentPaasFormEntityExts.size();
                HashMap<String, Long> paymentTaskHashMap = new HashMap<>(sizeSen * 2);
                paymentTaskPaasFormEntityExts.forEach(paasFormEntityExt -> paymentTaskHashMap.put(paasFormEntityExt.getCorpid(), paasFormEntityExt.getMenuId()));

                //找出应收款菜单，并把应收款的菜单id改成应收款的菜单id
                List<UserConfigEntity> updateList = new ArrayList<>();
                for (UserConfigEntity userConfigEntity : userConfigDaoEntitys) {
                    //需要更新的标记则为true
                    boolean updateTag = false;
                    String corpid = userConfigEntity.getCorpid();
                    //应收款的菜单
                    Long paymentMenuId = hashMap.get(corpid);
                    String configValue = userConfigEntity.getConfigValue();
                    List<MenuReturnPojo> quickNewFormList = JSONObject.parseArray(configValue, MenuReturnPojo.class);
                    for (MenuReturnPojo menuReturnPojo : quickNewFormList) {
                        if (menuReturnPojo.getMenuId().equals(paymentMenuId)) {
                            //回款计划的菜单
                            Long paymentTaskMenuId = paymentTaskHashMap.get(corpid);
                            menuReturnPojo.setMenuId(paymentTaskMenuId);
                            updateTag = true;
                        }
                    }
                    //封装好参数之后，需要重新重新拼接返回
                    if (!updateTag) {
                        continue;
                    }
                    String newConfigValue = JSON.toJSONString(quickNewFormList);
                    userConfigEntity.setConfigValue(newConfigValue);
                    updateList.add(userConfigEntity);
                }
                //进行批量更新菜单表
                if (CollectionsUtil.isNotEmpty(updateList)) {
                    userConfigModel.updateBatchAll(updateList);
                }
                idGte = userConfigDaoEntitys.get(userConfigDaoEntitys.size() - 1).getId();
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/paymentTask/fixUserPaymentTaskMenuId over");
        } catch (Exception e) {
            LOG.error("/script/paymentTask/fixUserPaymentTaskMenuId  error", e);
            return JSON.toJSONString("{\"msg\":\"fail\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }


    /**
     * 获取表单相关信息
     *
     * @param businessType 业务类型
     * @param corpidSet    公司id列表
     * @return
     */
    private List<PaasFormEntityExt> getPaasFormEntityList(int businessType, Set<String> corpidSet) {
        Map<String, Object> paasFormparam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String showColums = "id, corpid, menu_id";
        paasFormparam.put("del", 0);
        paasFormparam.put("businessType", businessType);
        paasFormparam.put("corpidIn", corpidSet);
        paasFormparam.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
        paasFormparam.put("columns", showColums);
        List<PaasFormEntityExt> paasFormEntityExts = paasFormModel.findEntitys(paasFormparam);
        return paasFormEntityExts;
    }


    /**
     * 需要同步老回款计划(应收款)的照片到新回款计划中
     *
     * @param paymentTaskMenuDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/migrateOldPaymentPicToPaymentTask", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String migrateOldPaymentPicToPaymentTask(@RequestBody @Valid PaymentTaskMenuDTO paymentTaskMenuDTO, BindingResult br) {
        try {
            LOG.info("-----------同步老回款计划(应收款)的照片到新回款计划中-----------");
            Integer shouldUpdateTime = paymentTaskMenuDTO.getShouldUpdateTime();
            Integer shouldUpdateEndTime = paymentTaskMenuDTO.getShouldUpdateEndTime();
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", 0);
            param.put("businessType", XbbRefTypeEnum.PAYMENT.getCode());
            param.put("shouldUpdateTime", shouldUpdateTime);
            param.put("shouldUpdateEndTime", shouldUpdateEndTime);
            List<CabinetFileEntity> cabinetFileModelEntitys = cabinetFileModel.findEntitys(param);
            cabinetFileModelEntitys.forEach(cabinetFileEntity -> cabinetFileEntity.setBusinessType(XbbRefTypeEnum.PAYMENT_TASK.getCode()));
            /**
             * 为啥不调用现成的批量插入的方法，是因为id要自动生成，不能用应收款的id
             */
            if (CollectionsUtil.isNotEmpty(cabinetFileModelEntitys)) {
                //tb_cabinet_file无更新时间，只能处理插入
                cabinetFileModel.insertBatchAll(cabinetFileModelEntitys);
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/paymentTask/migrateOldPaymentPicToPaymentTask over");
        }catch (Exception e) {
            LOG.error("/script/paymentTask/migrateOldPaymentPicToPaymentTask  error", e);
            return JSON.toJSONString("{\"msg\":\"fail\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }


    /**
     * 迁移老回款计划的操作权限到新回款计划中
     *老回款计划有的操作权限 208:回款计划菜单  326:回款查看 331:回款新建 127:回款编辑 273:回款删除 136:回款导出
     *新回款计划的操作权限  628:新回款计划菜单  629:新回款计划查看 630:新回款计划新建 631:新回款计划编辑 632:新回款计划删除 633:新回款计划导出
     *
     * @param paymentTaskMigrateDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/migrateOldPaymentPerToPaymentTask", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String migrateOldPaymentPerToPaymentTask(@RequestBody @Valid PaymentTaskMigrateDTO paymentTaskMigrateDTO, BindingResult br) {
        try {
            LOG.info("-----------迁移老回款计划的操作权限到新回款计划中-----------");
            //下面是角色相关的
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            String roleColumns = "id, permissions";
            param.put("del", 0);
            Long maxId = roleModel.getMaxId(param);
            param.put("columns", roleColumns);
            Integer start = 0;
            //每次查询500条
            Integer pageNum = 500;
            int idGte = 0;
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            long timeStart = DateTimeUtil.getInt();
            while(true) {
                param.put("idGte", idGte);
                LOG.warn("处理进度：已处理到 tb_role.id " + idGte + " / " + maxId);
                List<RoleEntity> roleEntities = roleModel.findAllRoleByCorpid(param);
                if (CollectionUtils.isEmpty(roleEntities)) {
                    break;
                }
                //代表需要更新的列表
                List<RoleEntity> updateList = new ArrayList<>();
                for (RoleEntity roleEntity : roleEntities) {
                    int roleId = roleEntity.getId();
                    //排除一些默认给的权限
                    if (roleId == 1 || roleId == 2 || roleId == 3 || roleId == 4 || roleId == 20) {
                        continue;
                    }
                    StringBuilder shouldContactStr = new StringBuilder();
                    String permissions = roleEntity.getPermissions();
                    String[] permissionsArray = permissions.split("\\|");
                    //代表是否需要更新的标记 true:需要 false:不需要
                    boolean shouldUpdateTag = false;
                    for (String permissonRole : permissionsArray) {
                        if ("208".equals(permissonRole)) {
                            shouldContactStr.append("628|");
                            shouldUpdateTag = true;
                        }else if("326".equals(permissonRole)) {
                            shouldContactStr.append("629|");
                            shouldUpdateTag = true;
                        }else if("331".equals(permissonRole)) {
                            shouldContactStr.append("630|");
                            shouldUpdateTag = true;
                        }else if("127".equals(permissonRole)) {
                            shouldContactStr.append("631|");
                            shouldUpdateTag = true;
                        }else if("273".equals(permissonRole)){
                            shouldContactStr.append("632|");
                            shouldUpdateTag = true;
                        }else if("136".equals(permissonRole)) {
                            shouldContactStr.append("633|");
                            shouldUpdateTag = true;
                        }
                    }
                    if (shouldUpdateTag) {
                        String finialStr = permissions+shouldContactStr.toString();
                        roleEntity.setPermissions(finialStr);
                        updateList.add(roleEntity);
                    }
                }
                //进行批量更新角色表
                roleModel.updateBatchAll(updateList);
                idGte = roleEntities.get(roleEntities.size() - 1).getId();
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/paymentTask/migrateOldPaymentPerToPaymentTask over");
        }catch (Exception e) {
            LOG.error("/script/paymentTask/migrateOldPaymentPerToPaymentTask  error", e);
            return JSON.toJSONString("{\"msg\":\"fail\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 下面这个方法主要是为了修改打印模板里面的信息
     *      1、应收款：（1）标题“回款计划”改为“应收款”  （2）“回款计划编号”改为“应收款编号” （3）“预计回款金额”改为“应收金额”
     *      2、回款单:
     *
     * @param paymentTaskMigrateDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/fixPrint", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixPrint(@RequestBody @Valid PaymentTaskMigrateDTO paymentTaskMigrateDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(paymentTaskMigrateDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }
        LOG.info("-----------fixPrint start 开始执行资金3期修改打印模板解释-----------");
        long timeStart = DateTimeUtil.getInt();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("del", 0);
        Integer businessTypePay = XbbRefTypeEnum.PAYMENT.getCode();
        Integer businessTypeSheet = XbbRefTypeEnum.PAYMENT_SHEET.getCode();
        param.put("businessTypeIn", Arrays.asList(businessTypePay, businessTypeSheet));
        try {
            Long maxId = paasPrintTemplateModel.getMaxId(param);
            Integer start = 0;
            //每次查询500条
            Integer pageNum = 500;
            Long idGte = 0L;
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            //param.put("corpid", "0");
            while (true) {
                param.put("idGte", idGte);
                LOG.warn("处理进度：已处理到 tb_paas_print_template.id " + idGte + " / " + maxId);
                List<PaasPrintTemplateEntity> paasPrintTemplateEntities = paasPrintTemplateModel.list(param);
                if (CollectionUtils.isEmpty(paasPrintTemplateEntities)) {
                    break;
                }
                idGte = paasPrintTemplateEntities.get(paasPrintTemplateEntities.size() - 1).getId();
                List<PaasPrintTemplateEntity> updateList = new ArrayList<>();
                for (PaasPrintTemplateEntity paasPrintTemplateEntity : paasPrintTemplateEntities) {
                    String html = paasPrintTemplateEntity.getHtml();
                    if (StringUtil.isEmpty(html)) {
                        continue;
                    }
                    JSONArray jsonArray = JsonHelperUtil.parseArray(html);
                    boolean updateTag = false;
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        if (Objects.isNull(jsonObject)) {
                            continue;
                        }
                        String type = jsonObject.getString("type");
                        if (Objects.equals(type, "title-show")) {
                            JSONObject optionJson = jsonObject.getJSONObject("options");
                            String mainTitleStr = optionJson.getString("mainTitle");
                            if (Objects.equals(mainTitleStr, "回款计划")) {
                                optionJson.put("mainTitle", "应收款");
                                updateTag = true;
                            }
                        } else if (Objects.equals(type, "multi-grids")) {
                            JSONObject optionJson = jsonObject.getJSONObject("options");
                            if (Objects.isNull(optionJson)) {
                                continue;
                            }
                            JSONObject field1Json = optionJson.getJSONObject("field1");
                            if (Objects.isNull(field1Json)) {
                                continue;
                            }
                            JSONObject jsonObjectThree = field1Json.getJSONObject("item");
                            if (Objects.isNull(jsonObjectThree)) {
                                continue;
                            }
                            String attr = jsonObjectThree.getString("attr");
                            if (paasPrintTemplateEntity.getBusinessType().equals(XbbRefTypeEnum.PAYMENT.getCode())) {
                                if (Objects.equals(attr, PaymentEnum.AMOUNT.getAttr())) {
                                    jsonObjectThree.put("attrName", "应收金额");
                                    field1Json.put("content", "应收金额");
                                    updateTag = true;
                                } else if (Objects.equals(attr, PaymentEnum.PAYMENT_NO.getAttr())) {
                                    jsonObjectThree.put("attrName", "应收款编号");
                                    field1Json.put("content", "应收款编号");
                                    updateTag = true;
                                }
                            } else if (paasPrintTemplateEntity.getBusinessType().equals(XbbRefTypeEnum.PAYMENT_SHEET.getCode())) {
                                if (attr.equals(PaymentSheetEnum.PAYMENT.getAttr())) {
                                    jsonObjectThree.put("attrName", "关联应收款");
                                    field1Json.put("content", "关联应收款");
                                    updateTag = true;
                                }
                            }
                        }
                    }
                    if (updateTag) {
                        //再把JSONArray变成字符串
                        String finialJson = JSONObject.toJSONString(jsonArray);
                        paasPrintTemplateEntity.setHtml(finialJson);
                        updateList.add(paasPrintTemplateEntity);
                    }
                }
                if (CollectionsUtil.isNotEmpty(updateList)) {
                    paasPrintTemplateModel.updateBatchAll(updateList);
                }

            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/paymentTask/fixPrint over");
        } catch (Exception e) {
            LOG.error("/script/paymentTask/fixPrint  error", e);
            return JSON.toJSONString("{\"msg\":\"fail\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     *
     *
     * @param paymentTaskMigrateDTO
     * @param br
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/migratePaymentTaskSubData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String migratePaymentTaskSubData(@RequestBody @Valid PaymentTaskMigrateDTO paymentTaskMigrateDTO, BindingResult br) throws Exception {
        try {
            LOG.info("-----------迁移回款计划子表单数据-----------");
            long timeStart = DateTimeUtil.getInt();
            Integer shouldUpdateTime = paymentTaskMigrateDTO.getShouldUpdateTime();
            Integer shouldUpdateEndTime = paymentTaskMigrateDTO.getShouldUpdateEndTime();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (Objects.nonNull(shouldUpdateEndTime)) {
                //代表是前置脚本
                param.put("del", 0);
            }
            param.put("shouldUpdateTime",shouldUpdateTime);
            param.put("shouldUpdateEndTime",shouldUpdateEndTime);
            Long maxId = paymentSubDataModel.getMaxId(param);
            Integer start = 0;
            //每次查询500条
            Integer pageNum = 500;
            Long idGte = 0L;
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            while (true) {
                param.put("idGte", idGte);
                LOG.warn("处理进度：已处理到 tb_saas_payment_sub_data.id " + idGte + " / " + maxId);
                List<? extends PaasFormSubDataEntity> paymentSubDataEntities = paymentSubDataModel.findEntitys(param);
                if (CollectionUtils.isEmpty(paymentSubDataEntities)) {
                    break;
                }
                idGte = paymentSubDataEntities.get(paymentSubDataEntities.size() - 1).getId();
                List<PaymentTaskSubDataEntity> paymentTaskSubDataInsertList = new ArrayList<>();
                List<PaymentTaskSubDataEntity> paymentTaskSubDataUpdateList = new ArrayList<>();
                //下面是具体的操作
                for (PaasFormSubDataEntity paymentSubDataEntity : paymentSubDataEntities) {
                    //因为应收款的id与回款计划的id是设计成一样的，所以下面能直接从应收款的子表单数据迁移到回款计划子表单中,然后subform_后面的数字要往上加1
                    //下面要区分哪些是新增的，哪些是更新的
                    PaymentTaskSubDataEntity paymentTaskSubDataEntity = new PaymentTaskSubDataEntity();
                    BeanUtil.copyProperties(paymentSubDataEntity, paymentTaskSubDataEntity);
                    String newAttr = "subForm_" + (Integer.parseInt(paymentTaskSubDataEntity.getAttr().substring(8, paymentSubDataEntity.getAttr().length())) + 1);
                    paymentTaskSubDataEntity.setAttr(newAttr);
                    if (Objects.nonNull(shouldUpdateEndTime)) {
                        //前置
                        paymentTaskSubDataInsertList.add(paymentTaskSubDataEntity);
                    }else {
                        //后置
                        if (paymentTaskSubDataEntity.getAddTime() < shouldUpdateTime && shouldUpdateTime < paymentTaskSubDataEntity.getUpdateTime()) {
                            paymentTaskSubDataUpdateList.add(paymentTaskSubDataEntity);
                        }else {
                            paymentTaskSubDataInsertList.add(paymentTaskSubDataEntity);
                        }
                    }
                }
                //去做更新和新增操作
                if (CollectionsUtil.isNotEmpty(paymentTaskSubDataInsertList)) {
                    //新增操作
                    paymentTaskSubDataModel.insertAllBatch(paymentTaskSubDataInsertList);
                }
                if (CollectionsUtil.isNotEmpty(paymentTaskSubDataUpdateList)) {
                    //更新子表单真的有点恶心，现在没有这种方法
                    paymentTaskSubDataModel.updateAllBatch(paymentTaskSubDataUpdateList);
                }
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/paymentTask/migratePaymentTaskSubData over");
        } catch (Exception e) {
            LOG.error("/script/paymentTask/migratePaymentTaskSubData  error", e);
            return JSON.toJSONString("{\"msg\":\"e\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     *  修复合并回款所产生的子回单与父回款单流程状态不一致问题
     * @param xbbCode
     * @param br
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/fixPaymentSheetFlowStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixPaymentFlowStatus(@RequestBody String xbbCode, BindingResult br) throws Exception {
        try {
//            if (!proBaseConfig.getXbbCode().equals(xbbCode)) {
//                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
//            }
            LOG.info("-----------修复审批合并回款子回款单的审批状态-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del",0);
            Integer start = 0;
            //每次查询500条
            Integer pageNum = 500;
            Long idGte = 0L;
            //param.put("corpid","1");
            param.put("aloneIn",Arrays.asList(SheetAloneEnum.PARENT.getCode(),SheetAloneEnum.CHILD.getCode()));
            param.put("flowStatusIn",Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(),FlowStatusEnum.PASS.getType(),FlowStatusEnum.IN_APPROVAL.getType()));
            Long maxId = paymentSheetModel.getMaxId(param);
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            while(true){
                param.put("idGte", idGte);
                LOG.warn("处理进度：已处理到 tb_saas_payment_sheet.id " + idGte + " / " + maxId);
                List<PaymentSheetEntityExt> paymentSheetEntitys = paymentSheetModel.findEntitys(param);
                if (CollectionUtils.isEmpty(paymentSheetEntitys)){
                    break;
                }
                idGte = paymentSheetEntitys.get(paymentSheetEntitys.size() - 1).getId();
                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                //根据uuid分组父子回款单
                Map<String, List<PaymentSheetEntityExt>> paymentSheetMap = paymentSheetEntitys.stream().collect(Collectors.groupingBy(PaymentSheetEntityExt::getUuid));
                for(Map.Entry<String,List<PaymentSheetEntityExt>> entry : paymentSheetMap.entrySet()){
                    List<PaymentSheetEntityExt> paymentSheetList = entry.getValue();
                    if (!CollectionUtils.isEmpty(paymentSheetList)){
                        //获取每组下面的子回款单列表
                        List<PaymentSheetEntityExt> subList = paymentSheetList.stream().filter(item -> Objects.equals(item.getAlone(), SheetAloneEnum.CHILD.getCode())).collect(Collectors.toList());
                        //子回款单的flowStatus更新成和父回款单一致
                        paymentSheetList.forEach(parentItem -> {
                            if (Objects.equals(parentItem.getAlone(),SheetAloneEnum.PARENT.getCode())){
                                subList.forEach(subItem -> {
                                    if (!Objects.equals(parentItem.getFlowStatus(),subItem.getFlowStatus())){
                                        UpdateDataEntity updateDataEntity = new UpdateDataEntity();
                                        subItem.setFlowStatus(parentItem.getFlowStatus());
                                        BeanUtil.copyProperties(subItem,updateDataEntity);
                                        updateDataEntityList.add(updateDataEntity);
                                    }
                                });
                            }
                        });
                    }
                }
                //对所有公司操作
                if(!CollectionUtils.isEmpty(updateDataEntityList)){
                    paymentSheetModel.updateFlowStatusBatch(updateDataEntityList,null);
                }
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/paymentTask/fixPaymentSheetFlowStatus over");
        } catch (Exception e) {
            LOG.error("/script/paymentTask/fixPaymentSheetFlowStatus  error", e);
            return JSON.toJSONString("{\"msg\":\"e\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }


    /**
     *  修复合并回款所产生的子付款单与父付款单流程状态不一致问题
     * @param xbbCode
     * @param br
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/fixPaySheetFlowStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixPaySheetFlowStatus(@RequestBody String xbbCode, BindingResult br) throws Exception {
        try {
//            if (!proBaseConfig.getXbbCode().equals(xbbCode)) {
//                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
//            }
            LOG.info("-----------修复审批合并付款子付款单的审批状态-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del",0);
            Integer start = 0;
            //每次查询500条
            Integer pageNum = 500;
            Long idGte = 0L;
            //param.put("corpid","1");
            param.put("aloneIn",Arrays.asList(SheetAloneEnum.PARENT.getCode(),SheetAloneEnum.CHILD.getCode()));
            param.put("flowStatusIn",Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(),FlowStatusEnum.PASS.getType(),FlowStatusEnum.IN_APPROVAL.getType()));
            Long maxId = payPlanSheetModel.getMaxId(param);
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            while(true){
                param.put("idGte", idGte);
                LOG.warn("处理进度：已处理到 tb_saas_pay_sheet.id " + idGte + " / " + maxId);
                List<PayPlanSheetEntityExt> paySheetEntitys = payPlanSheetModel.findEntitys(param);
                if (CollectionUtils.isEmpty(paySheetEntitys)){
                    break;
                }
                idGte = paySheetEntitys.get(paySheetEntitys.size() - 1).getId();
                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                //根据uuid分组父子付款单
                Map<String, List<PayPlanSheetEntityExt>> paymentSheetMap = paySheetEntitys.stream().collect(Collectors.groupingBy(PayPlanSheetEntityExt::getUuid));
                for(Map.Entry<String,List<PayPlanSheetEntityExt>> entry : paymentSheetMap.entrySet()){
                    List<PayPlanSheetEntityExt> paySheetList = entry.getValue();
                    if (!CollectionUtils.isEmpty(paySheetList)){
                        //获取每组下面的子付款单列表
                        List<PayPlanSheetEntityExt> subList = paySheetList.stream().filter(item -> Objects.equals(item.getAlone(), SheetAloneEnum.CHILD.getCode())).collect(Collectors.toList());
                        //子付款单的flowStatus更新成和父付款单一致
                        paySheetList.forEach(parentItem -> {
                            if (Objects.equals(parentItem.getAlone(),SheetAloneEnum.PARENT.getCode())){
                                subList.forEach(subItem -> {
                                    if (!Objects.equals(parentItem.getFlowStatus(),subItem.getFlowStatus())){
                                        UpdateDataEntity updateDataEntity = new UpdateDataEntity();
                                        subItem.setFlowStatus(parentItem.getFlowStatus());
                                        BeanUtil.copyProperties(subItem,updateDataEntity);
                                        updateDataEntityList.add(updateDataEntity);
                                    }
                                });
                            }
                        });
                    }
                }
                //对所有公司操作
                if(!CollectionUtils.isEmpty(updateDataEntityList)){
                    payPlanSheetModel.updateFlowStatusBatch(updateDataEntityList,null);
                }
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/paymentTask/fixPaySheetFlowStatus over");
        } catch (Exception e) {
            LOG.error("/script/paymentTask/fixPaySheetFlowStatus  error", e);
            return JSON.toJSONString("{\"msg\":\"e\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

}
